﻿using System;
using System.Collections.Generic;
using System.Text;
using Casamiel.Domain.Entity;

namespace Casamiel.Application.Services
{
	public class MapService : IMapService
	{
		public double GetGistance(Map from, Map to)
		{
			if (from is null) {
				throw new ArgumentNullException(nameof(from));
			}

			if (to is null) {
				throw new ArgumentNullException(nameof(to));
			}

			return Distance(from.lat, from.lng, to.lat, to.lng);
		}

        private double HaverSin(double theta)
		{
			var v = Math.Sin(theta / 2);
			return v * v;
		}


	    readonly	 double EARTH_RADIUS = 6371.0;//km 地球半径 平均值，千米

		/// <summary>
		/// 给定的经度1，纬度1；经度2，纬度2. 计算2个经纬度之间的距离。
		/// </summary>
		/// <param name="lat1">经度1</param>
		/// <param name="lon1">纬度1</param>
		/// <param name="lat2">经度2</param>
		/// <param name="lon2">纬度2</param>
		/// <returns>距离（公里、千米）</returns>
		private  double Distance(double lat1, double lon1, double lat2, double lon2)
		{
			//用haversine公式计算球面两点间的距离。
			//经纬度转换成弧度
			lat1 = ConvertDegreesToRadians(lat1);
			lon1 = ConvertDegreesToRadians(lon1);
			lat2 = ConvertDegreesToRadians(lat2);
			lon2 = ConvertDegreesToRadians(lon2);

			//差值
			var vLon = Math.Abs(lon1 - lon2);
			var vLat = Math.Abs(lat1 - lat2);

			//h is the great circle distance in radians, great circle就是一个球体上的切面，它的圆心即是球心的一个周长最大的圆。
			var h = HaverSin(vLat) + Math.Cos(lat1) * Math.Cos(lat2) * HaverSin(vLon);

			var distance = 2 * EARTH_RADIUS * Math.Asin(Math.Sqrt(h));

			return distance;
		}

		/// <summary>
		/// 将角度换算为弧度。
		/// </summary>
		/// <param name="degrees">角度</param>
		/// <returns>弧度</returns>
		private  double ConvertDegreesToRadians(double degrees)
		{
			return degrees * Math.PI / 180;
		}

		private  double ConvertRadiansToDegrees(double radian)
		{
			return radian * 180.0 / Math.PI;
		}
	}
}
